Cloud9でLambda Layerに依存するJavaのLambdaをローカル実行する
Cloud9でJavaのLambdaを開発する際に、ちょっとLambdaを実行してみて動作確認をしたいことがよくありました。
しかし、動作確認のたびにLambdaを再デプロイするのは面倒くさいです。 そこで、 SAM(Serverless Application Model) を利用すれば、Lambdaのローカル実行が可能です。
今回、Cloud9上でLambda Layerに依存するJavaのLambdaをローカルで実行する機会があったので、その方法を紹介します。
前提
Cloud9でJavaのLambdaをデプロイする環境は、先日書いたブログと同様の環境がすでに構築されていることを前提にします。
また、SAMでDockerを利用する関係上、Dockerイメージをローカルにダウンロードするたディスク容量がそれなりに必要です。 デフォルトの8GBだと不足する可能性があります。
その場合、次のブログを参考にしてディスクサイズを拡張してください。
Layerを含むLambdaのローカル実行イメージ
SAMの sam local invoke
コマンドを利用することで、Lambdaをローカル実行できます。
Lambda Layerを含むLambdaも同じ様にローカル実行できますが、次の図のようにLayer部分だけはデプロイされているLambda Layerを参照してローカルホストにキャッシュします。 そのため、Lambdaのローカル実行したい場合、依存するLambda Layer部分は先にデプロイしておく必要があります。
SAMテンプレートの修正
Lambda Layerに依存するLambdaをローカル実行したい場合、SAMテンプレートのLayerの指定に !Ref
組込み関数は使うとうまくいきません。
ARNを直接指定する必要があります。
AWSTemplateFormatVersion: '2010-09-09' Transform: 'AWS::Serverless-2016-10-31' Description: An AWS Lambda application that calls the Lambda API. Resources: function: Type: AWS::Serverless::Function Properties: CodeUri: build/distributions/blank-java.zip Handler: example.Handler::handleRequest Runtime: java11 Description: Java function MemorySize: 512 Timeout: 10 # Function's execution role Policies: - AWSLambdaBasicExecutionRole - AWSLambdaReadOnlyAccess - AWSXrayWriteOnlyAccess - AWSLambdaVPCAccessExecutionRole Tracing: Active Layers: - !Ref libs libs: Type: AWS::Serverless::LayerVersion Properties: LayerName: blank-java-lib Description: Dependencies for the blank-java sample app. ContentUri: build/blank-java-lib.zip CompatibleRuntimes: - java11
デプロイされたLambda LayerのARNはマネジメントコンソール等で確認してください。
そしてSAMテンプレートのLambdaが依存するLayerをARNでの指定に変更します。
AWSTemplateFormatVersion: '2010-09-09' Transform: 'AWS::Serverless-2016-10-31' Description: An AWS Lambda application that calls the Lambda API. Resources: function: Type: AWS::Serverless::Function Properties: CodeUri: build/distributions/blank-java.zip Handler: example.Handler::handleRequest Runtime: java11 Description: Java function MemorySize: 512 Timeout: 10 # Function's execution role Policies: - AWSLambdaBasicExecutionRole - AWSLambdaReadOnlyAccess - AWSXrayWriteOnlyAccess - AWSLambdaVPCAccessExecutionRole Tracing: Active Layers: # - !Ref libs - 'arn:aws:lambda:ap-northeast-1:123456789012:layer:blank-java-lib:8' libs: Type: AWS::Serverless::LayerVersion Properties: LayerName: blank-java-lib Description: Dependencies for the blank-java sample app. ContentUri: build/blank-java-lib.zip CompatibleRuntimes: - java11
Lambdaのローカル実行
SAMテンプレートでLayerをARNで指定すれば、 次のように sam local invoke
コマンドでLambdaのローカル実行ができます。
$ cd ~/environment/aws-lambda-developer-guide/sample-apps/blank-java $ sam local invoke -e event.json
Lambda Layerパッケージは、デフォルトでは ~/.aws-sam/layers-pkg/
にキャッシュされます。
sam local invoke
実行後に確認すると、Layerパッケージが自動でダウンロードされキャッシュされていることがわかります。
$ ls ~/.aws-sam/layers-pkg/ blank-java-lib-8-14f4e6cb4d
終わりに
Cloud9でLambda Layerに依存するJavaのLambdaのローカル実行をやってみました。
Lambdaのプログラムを修正して、ちょっとテスト実行してみたいことがよくあると思いますが、そのたびに再デプロイするのはちょっと面倒くさいです。 SAMの機能を使ってローカルでサッと実行して動作が確認できると開発しやすいと思います。